package com.study.juc.lk;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.LockSupport;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @program: juc-study
 * @author: jzhou
 * @date: 2022-08-13 17:20
 * @version: 1.0
 * @description: 线程的等待和唤醒
 **/
public class LockSupportDemo {
	public static void main(String[] args) {
		//正常使用+不需要锁块
		Thread t1 = new Thread(() -> {
			//暂停几秒钟线程
			try {
				TimeUnit.SECONDS.sleep(2);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println(Thread.currentThread().getName() + "\t" + "----come in");
			LockSupport.park();
			LockSupport.park(); //许可证只有一个，再次调用该方法线程会阻塞
			System.out.println(Thread.currentThread().getName() + "\t" + "------被唤醒");
		}, "t1");
		t1.start();

		//暂停几秒钟线程
		try {
			TimeUnit.SECONDS.sleep(1);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}

		new Thread(() -> {
			LockSupport.unpark(t1);
			LockSupport.unpark(t1); //最多也只能有一个，累加无效
			LockSupport.unpark(t1);
			System.out.println(Thread.currentThread().getName() + "\t" + "-----发出通知");
		},"t2").start();



	}

	/**
	 * 通过 condition.await()  condition.signal() 停止和唤醒线程
	 */
	private static void syncAwaitSignal() {
		Lock lock = new ReentrantLock();
		Condition condition = lock.newCondition();

		new Thread(() -> {
			lock.lock();
			try
			{
				System.out.println(Thread.currentThread().getName()+"\t"+"start");
				condition.await();
				System.out.println(Thread.currentThread().getName()+"\t"+"被唤醒");
			} catch (InterruptedException e) {
				e.printStackTrace();
			} finally {
				lock.unlock();
			}
		},"t1").start();

		//暂停几秒钟线程
		try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); }

		new Thread(() -> {
			lock.lock();
			try
			{
				condition.signal();
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				lock.unlock();
			}
			System.out.println(Thread.currentThread().getName()+"\t"+"发起通知了");
		},"t2").start();
	}

	/**
	 * 通过 objectLock.wait(); objectLock.notify(); 停止和唤醒线程
	 */
	private static void syncWaitNotify() {
		Object objectLock = new Object(); //同一把锁，类似资源类

		new Thread(() -> {
			synchronized (objectLock) {
				System.out.println(Thread.currentThread().getName() + "\t" + "-----come in");
				try {
					objectLock.wait();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			System.out.println(Thread.currentThread().getName() + "\t" + "被唤醒了");
		}, "t1").start();

		//暂停几秒钟线程
		try {
			TimeUnit.SECONDS.sleep(2L);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}

		new Thread(() -> {
			synchronized (objectLock) {
				objectLock.notify();
				System.out.println(Thread.currentThread().getName() + "\t" + "发起通知");
			}
		}, "t2").start();
	}
}
